package com.qding.park.common.core.aspect.handle;

import java.lang.reflect.Method;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import com.qding.park.common.core.annotation.MethodCacheable;
import com.qding.park.common.core.aspect.ExpContextHelper;
import com.qding.park.common.core.aspect.context.CacheableContext;
import com.qding.park.common.core.exceptions.ExceptionMessage;
import com.qding.park.common.core.exceptions.frame.cache.FrameCacheException;
import com.qding.park.common.core.redis.JedisClient;
import com.qding.park.common.core.redis.SerializeUtils;

/**
 * @ClassName MethodCacheableHandler
 * @Description TODO( MethodCacheable 处理)
 * @author Administrator
 * @Date 2016年10月15日 下午9:39:20
 * @version 1.0.0
 */
public class MethodCacheableHandler extends AbstractCacheHandle{
	private final static Log _log = LogFactory.getLog(MethodCacheableHandler.class);
	
	/**
	 * @Field @methodCacheable : TODO(MethodCacheable 注解)
	 */
	private MethodCacheable methodCacheable;

	/**
	 * @Field @pjp : TODO(MethodCacheable 注解的切面 )
	 */
	private ProceedingJoinPoint pjp;
	
	
	
	/**
	 * @throws Throwable 
	 * @Description (执行 缓存业务)
	 */
	public Object doCache(MethodCacheable cacheable, ProceedingJoinPoint pjpoint,JedisClient jedisClient) throws Throwable {
		
		// 得到缓存开关
		MethodCacheable.CACHESWITCH cacheSwitch = cacheable.cacheSwitch();
		
		//得到上下文环境
		CacheableContext context=ExpContextHelper.createCacheContext( cacheable,  pjpoint, jedisClient);
		
		if (cacheSwitch == MethodCacheable.CACHESWITCH.OFF) {
			// 关闭了缓存
			Object result = pjpoint.proceed(pjpoint.getArgs());
			return result;
		} else {
			// 开启缓存
			
			// 业务类型
			MethodCacheable.SERVICETYPE serviceType = cacheable.serviceType();

			int expire=context.getExpire();
			
			
			if (serviceType == MethodCacheable.SERVICETYPE.NULL) {
				// 不执行业务方法
				Object returnObj = context.getCache_value();
				return SerializeUtils.unSerialize((String)returnObj, context.getReturnType());
			} else if (serviceType == MethodCacheable.SERVICETYPE.BEFORE) {
				// 在业务方法之前执行
				Object returnObj = context.getCache_value();// 从缓存之中获取
				returnObj=SerializeUtils.unSerialize((String)returnObj, context.getReturnType());
				if (returnObj == null) {
					// 如果缓存没有
					returnObj = pjpoint.proceed(pjpoint.getArgs());
					this.saveCache( context,  jedisClient, SerializeUtils.serialize(returnObj));
				}
				return returnObj;

			} else if (serviceType == MethodCacheable.SERVICETYPE.AFTER) {
				// 在业务方法之后执行
				Object returnObj = pjpoint.proceed(pjpoint.getArgs());
				if(returnObj!=null){
					this.saveCache( context,  jedisClient, SerializeUtils.serialize(returnObj));
				}
				return returnObj;
			} else {
				return pjpoint.proceed(pjpoint.getArgs());
			}

		}
	}

	
	
//	public Object doCache(JedisClient jedisClient) throws Throwable {
//		return doCache(methodCacheable,pjp,jedisClient);
//	}

	public MethodCacheable getMethodCacheable() {
		return methodCacheable;
	}
	


	private Method getMethod(ProceedingJoinPoint pjp) {
		MethodSignature signature = (MethodSignature) pjp.getSignature();
		Method method = signature.getMethod();

		return method;

	}
	public void setMethodCacheable(MethodCacheable methodCacheable) {
		this.methodCacheable = methodCacheable;
	}

	public ProceedingJoinPoint getPjp() {
		return pjp;
	}

	public void setPjp(ProceedingJoinPoint pjp) {
		this.pjp = pjp;
	}

}
